package lab4;

import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class Multiple implements Runnable{
	
	private int index;
	private int gap;
	private double[][] matrixA;
	private double[][] matrixB;
	private double[][] result;
	private CountDownLatch countDownLatch;
	
	public Multiple(int index, int gap, double[][] matrixA, double[][] matrixB, double[][] result,
			CountDownLatch countDownLatch) {
		super();
		this.index = index;
		this.gap = gap;
		this.matrixA = matrixA;
		this.matrixB = matrixB;
		this.result = result;
		this.countDownLatch = countDownLatch;
	}

	@Override
	public void run() {	
		for (int i = index * gap; i < (index + 1) * gap && i < matrixA.length; i++) {
			for (int j = 0; j <  matrixB[0].length; j++) {
				for (int k = 0; k <  matrixB.length; k++)
					result[i][j] += matrixA[i][k] *  matrixB[k][j];
			}
		}
		
		countDownLatch.countDown();	
	}
	
	public static void main(String[] args) {
		
		long startTime;
		long endTime;
		//随机生成矩阵大小
		Random ran = new Random();
		int a = 100;
		int b = 200;
		int c = 500;
		System.out.println("矩阵大小：" + a + "*" + b + " " + b + "*" + c);
		//随机生成矩阵中元素
		MatrixGenerator matrix1 = new MatrixGenerator(a,b);
		MatrixGenerator matrix2 = new MatrixGenerator(b,c);
	
		double[][] matrixA = matrix1.generate(a,b);
		
    	double[][] matrixB = matrix2.generate(b,c);		
		
		//串行计算
		double[][] result1 = new double[a][c];
	    startTime = System.currentTimeMillis();
		for(int i = 0 ; i < matrixA.length ;i++) {
			for(int j = 0 ; j < matrixB[0].length ; j++) {
				for(int k = 0 ; k < matrixA[0].length ; k++) {
					result1[i][j] +=  matrixA[i][k] * matrixB[k][j];
				}
			}
		}
		endTime = System.currentTimeMillis();
		System.out.println("计算结果：");
		for(int i = 0 ; i < result1.length ;i++) {
			for(int j = 0 ; j < result1[i].length ; j++) {
				System.out.print(result1[i][j] + "  ");
			}
			System.out.println();
		}
		System.out.println("串行运行时间" + (endTime - startTime) + '\n');
		
		//并行计算
		double[][] result2 = new double[a][c];
		int threadNum = 5;//线程数5
		int gap = matrixA.length / threadNum + 1;
		
		CountDownLatch countDownLatch = new CountDownLatch(threadNum);
		startTime = System.currentTimeMillis();

		for (int i = 0; i < threadNum; i++) {
			Multiple multiple = new Multiple(i, gap, matrixA, matrixB, result2, countDownLatch);
			Thread th = new Thread(multiple);
			th.start();
		}
		
		try {
			countDownLatch.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		endTime = System.currentTimeMillis();

		System.out.println("计算结果：");
		for(int i = 0 ; i < result2.length ;i++) {
			for(int j = 0 ; j < result2[i].length ; j++) {
				System.out.print(result2[i][j] + "  ");
			}
			System.out.println();
		}
		System.out.println("并行运行时间" + (endTime - startTime));
	}
}
